package com.yaodian100.ec.payment.service.impl;

import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.annotation.Resource;

import net.sf.json.JSON;
import net.sf.json.JSONSerializer;

import org.apache.commons.betwixt.io.BeanWriter;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.exception.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;

import com.yaodian100.core.batch.service.BatchJobService;
import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.common.utils.ServerValue;
import com.yaodian100.core.logger.service.LogService;
import com.yaodian100.core.mail.entity.Mail;
import com.yaodian100.core.mail.service.MailService;
import com.yaodian100.ec.creditcard.entity.CreditcardDetail;
import com.yaodian100.ec.creditcard.service.CreditcardService;
import com.yaodian100.ec.order.entity.Orders;
import com.yaodian100.ec.order.service.OrderService;
import com.yaodian100.ec.payment.entity.ThirdPartyTransfer;
import com.yaodian100.ec.payment.entity.ThirdPartyTransferFail;
import com.yaodian100.ec.payment.entity.ThirdPartyTransferLog;
import com.yaodian100.ec.payment.service.ThirdpartyPaymentService;
import com.yaodian100.ec.payment.service.ThirdpartyTransferFailService;
import com.yaodian100.ec.payment.service.ThirdpartyTransferLogService;
import com.yaodian100.ec.payment.service.TransferService;

public class ThirdpartyPaymentServiceImpl implements ThirdpartyPaymentService {
	private static final Logger logger = LoggerFactory.getLogger(ThirdpartyPaymentServiceImpl.class);
	@Autowired
	private OrderService orderService;
	@Autowired
	private TransferService transferService;
	@Autowired
	private ThirdpartyTransferLogService thirdpartyTransferLogService;
	@Autowired
	private ThirdpartyTransferFailService thirdpartyTransferFailService;
	@Autowired
	private MailService mailService;
	@Autowired
	private LogService logService;
	@Autowired
	private BatchJobService batchJobService;
	@Resource
	private JdbcTemplate jdbcTemplate;
	@Resource
	private CreditcardService creditcardService;

	private String keyPath;
	private String chinapayId;
	private String alipayDirectPartnerId;
	private String alipayDirectKey;
	private String alipayDanbaoPartnerId;
	private String alipayDanbaoKey;
	private String alipaySellerId;
	private String quickmoneyId;
	private String quickmoneyKey;
	private String quickmoneyInstallmentKey;
	private String tenpayId;
	private String tenpayKey;

	// private static String hostAddress = ServerValue.getFrontHostname() + ServerValue.getFrontContextPath();

	// private static String hostAddress = "http://sitmall.yaodian100.com/ecmall";

	/**
	 * @param keyPath the keyPath to set
	 */
	public void setKeyPath(String keyPath) {
		this.keyPath = keyPath;
	}

	/**
	 * @param chinapayId the chinapayId to set
	 */
	public void setChinapayId(String chinapayId) {
		this.chinapayId = chinapayId;
	}

	/**
	 * @param alipayDirectPartnerId the alipayDirectPartnerId to set
	 */
	public void setAlipayDirectPartnerId(String alipayDirectPartnerId) {
		this.alipayDirectPartnerId = alipayDirectPartnerId;
	}

	/**
	 * @param alipayDirectKey the alipayDirectKey to set
	 */
	public void setAlipayDirectKey(String alipayDirectKey) {
		this.alipayDirectKey = alipayDirectKey;
	}

	/**
	 * @param alipayDanbaoPartnerId the alipayDanbaoPartnerId to set
	 */
	public void setAlipayDanbaoPartnerId(String alipayDanbaoPartnerId) {
		this.alipayDanbaoPartnerId = alipayDanbaoPartnerId;
	}

	/**
	 * @param alipayDanbaoKey the alipayDanbaoKey to set
	 */
	public void setAlipayDanbaoKey(String alipayDanbaoKey) {
		this.alipayDanbaoKey = alipayDanbaoKey;
	}

	/**
	 * @param alipaySellerId the alipaySellerId to set
	 */
	public void setAlipaySellerId(String alipaySellerId) {
		this.alipaySellerId = alipaySellerId;
	}

	/**
	 * @param quickmoneyId the quickmoneyId to set
	 */
	public void setQuickmoneyId(String quickmoneyId) {
		this.quickmoneyId = quickmoneyId;
	}

	/**
	 * @param quickmoneyKey the quickmoneyKey to set
	 */
	public void setQuickmoneyKey(String quickmoneyKey) {
		this.quickmoneyKey = quickmoneyKey;
	}

	/**
	 * @param tenpayId the tenpayId to set
	 */
	public void setTenpayId(String tenpayId) {
		this.tenpayId = tenpayId;
	}

	/**
	 * @param tenpayKey the tenpayKey to set
	 */
	public void setTenpayKey(String tenpayKey) {
		this.tenpayKey = tenpayKey;
	}

	/**
	 * @param quickmoneyInstallmentKey the quickmoneyInstallmentKey to set
	 */
	public void setQuickmoneyInstallmentKey(String quickmoneyInstallmentKey) {
		this.quickmoneyInstallmentKey = quickmoneyInstallmentKey;
	}

	@Override
	public Map<String, String> alipaySend(String orderId, String alipayType, String bankCode, String token) {
		Orders order = orderService.get(orderId);
		String partnerId = null;
		String key = null;
		String serviceType = null;
		String aliNotifyURL = null;
		String aliRetunrURL = null;

		// trade_create_by_buyer實物
		// create_direct_pay_by_user即時,
		// create_partner_trade_by_buyer擔保
		if ("direct".equals(alipayType)) {
			partnerId = alipayDirectPartnerId;
			key = alipayDirectKey;
			serviceType = "create_direct_pay_by_user";
			aliNotifyURL = "alipayNotify.do";
			aliRetunrURL = "alipayReturn.do";
		} else if ("danbao".equals(alipayType)) {
			partnerId = alipayDanbaoPartnerId;
			key = alipayDanbaoKey;
			serviceType = "create_partner_trade_by_buyer";
			aliNotifyURL = "alipayDanbaoNotify.do";
			aliRetunrURL = "alipayDanbaoReturn.do";
		} else if ("duo".equals(alipayType)) {
			partnerId = alipayDirectPartnerId;
			key = alipayDirectKey;
			serviceType = "trade_create_by_buyer";
			aliNotifyURL = "alipayNotify.do";
			aliRetunrURL = "alipayReturn.do";
		} else {
			partnerId = alipayDirectPartnerId;
			key = alipayDirectKey;
			serviceType = "create_direct_pay_by_user";
			aliNotifyURL = "alipayNotify.do";
			aliRetunrURL = "alipayReturn.do";
		}

		// *******************************************
		Map<String, String> signParams = new TreeMap<String, String>();// 按照key作排序产生检查码

		signParams.put("service", serviceType);
		signParams.put("out_trade_no", orderId);// 订单编号
		signParams.put("quantity", "1");
		signParams.put("partner", partnerId);
		signParams.put("payment_type", "1");
		if (StringUtils.isNotBlank(bankCode)) {
			signParams.put("paymethod", "bankPay");
			signParams.put("defaultbank", bankCode);
		}
		signParams.put("discount", "0");
		signParams.put("notify_url", ServerValue.getFrontHostname() + ServerValue.getFrontContextPath() + "/payment/"
				+ aliNotifyURL);
		signParams.put("price", order.getJoinMustPay().toString());
		signParams.put("logistics_type", "EXPRESS");
		signParams.put("logistics_fee", "0");
		signParams.put("logistics_payment", "BUYER_PAY");
		signParams.put("return_url", ServerValue.getFrontHostname() + ServerValue.getFrontContextPath() + "/payment/"
				+ aliRetunrURL);
		signParams.put("seller_id", alipaySellerId);
		signParams.put("subject", "耀点100商品");
		signParams.put("_input_charset", "utf-8");
		if (StringUtils.isNotBlank(token)) {
			signParams.put("token", token);
		}

		// *************************************************

		Map<String, String> sendParams = new TreeMap<String, String>(signParams);
		sendParams.remove("_input_charset");// 不作为hidden，而是作为action url的一部分
		sendParams.put("sign", new String(DigestUtils.md5Hex(getContent(signParams, key))));
		sendParams.put("sign_type", "MD5");

		saveSendLog(orderId, order.getJoinMustPay(), "alipay", "04", bankCode);
		return sendParams;
	}

	@Override
	public boolean alipayNotify(Map<String, String> params) {
		String tid = null;
		String orderId = null;
		BigDecimal amount = null;
		boolean isSuccess = false;
		String srcType = "04";
		if (params.containsKey("danbao")) {
			srcType = "05";
		}

		if (alipayVerify(params)) {
			if (params.containsKey("trade_no") && params.containsKey("total_fee") && params.containsKey("out_trade_no")) {

				tid = params.get("trade_no");
				amount = new BigDecimal(params.get("total_fee")).setScale(2);
				orderId = params.get("out_trade_no");

				if ("05".equals(srcType)) {// 担保交易处理
					if (params.containsKey("trade_status")) {// 担保交易判断的必要参数
						String tradeStatus = params.get("trade_status");
						if ("TRADE_CLOSED".equals(tradeStatus)) {// 交易关闭时当作失败处理
							isSuccess = insertFailTransfer(orderId, amount, tid, srcType, "支付宝担保交易：交易关闭 ", "", params);
						} else {
							isSuccess = processThirdparty(orderId, amount, tid, srcType, "", params);
						}
					} else {
						insertFailTransfer(orderId, amount, tid, srcType, "缺少参数", "", params);
					}
				} else {// 非担保交易处理
					isSuccess = processThirdparty(orderId, amount, tid, srcType, "", params);
				}
			} else {
				insertFailTransfer(orderId, amount, tid, srcType, "缺少参数", "", params);

			}
		} else {
			// insertFailTransfer(orderId, amount, tid, "04", "签名验证错误", "", params);
			insertFailTwice("签名验证错误", params, srcType);
		}
		return isSuccess;
	}

	@Override
	public boolean alipayReturn(Map<String, String> params) {
		String tid = null;
		String orderId = null;
		BigDecimal amount = null;
		boolean isSuccess = false;
		String srcType = "04";
		if (params.containsKey("danbao")) {
			srcType = "05";
		}

		if (alipayVerify(params)) {
			if (params.containsKey("trade_no") && params.containsKey("total_fee") && params.containsKey("out_trade_no")) {
				tid = params.get("trade_no");
				amount = new BigDecimal(params.get("total_fee")).setScale(2);
				orderId = params.get("out_trade_no");
				if ("05".equals(srcType)) {// 担保交易处理
					if (params.containsKey("trade_status")) {// 担保交易判断的必要参数
						String tradeStatus = params.get("trade_status");
						if ("TRADE_CLOSED".equals(tradeStatus)) {// 交易关闭时当作失败处理
							isSuccess = insertFailTransfer(orderId, amount, tid, srcType, "支付宝担保交易：交易关闭 ", "", params);
						} else {
							isSuccess = processThirdparty(orderId, amount, tid, srcType, "", params);
						}
					} else {
						insertFailTransfer(orderId, amount, tid, srcType, "缺少参数", "", params);
					}
				} else {// 非担保交易处理
					isSuccess = processThirdparty(orderId, amount, tid, srcType, "", params);
				}
			} else {
				insertFailTransfer(orderId, amount, tid, srcType, "缺少参数", "", params);

			}
		} else {
			// insertFailTransfer(orderId, amount, tid, "04", "签名验证错误", "", params);
			insertFailTwice("签名验证错误", params, srcType);
		}
		return isSuccess;
	}

	private boolean alipayVerify(Map<String, String> params) {
		boolean isVaild = false;
		Map<String, String> checkParams = new TreeMap<String, String>(params);
		if (checkParams.containsKey("sign")) {
			String sign = checkParams.get("sign");
			checkParams.remove("sign");
			checkParams.remove("sign_type");
			// if (params.containsKey("subject")) {
			// try {
			// checkParams.put("subject", new String(params.get("subject").getBytes("ISO-8859-1"), "UTF-8"));
			// } catch (UnsupportedEncodingException e) {
			// // TODO Auto-generated catch block
			// e.printStackTrace();
			// }
			// }
			// 由於使用者自行回傳時可能造成中文編碼不同的問題，因此仍是寫死。
			checkParams.put("subject", "耀点100商品");

			String chkSign = DigestUtils.md5Hex(getContent(checkParams, alipayDirectKey));
			if (chkSign.equalsIgnoreCase(sign)) {
				isVaild = true;
			} else {
				checkParams.put("subject", "耀点商品");// 舊title
				chkSign = DigestUtils.md5Hex(getContent(checkParams, alipayDirectKey));
				if (chkSign.equalsIgnoreCase(sign)) {
					isVaild = true;
				}
			}

		}
		return isVaild;
	}

	@Override
	public Map<String, String> chinapaySend(String orderId) {
		Orders order = orderService.get(orderId);
		chinapay.PrivateKey key = new chinapay.PrivateKey();
		chinapay.SecureLink t;

		boolean flag;
		flag = key.buildKey(chinapayId, 0, keyPath + "/chinapay/MerPrk.key");

		t = new chinapay.SecureLink(key);

		// ******************************************************
		String merIdKey = chinapayId.substring(10);
		// String orderId10 = orderId.substring(2);// 订单编号前两位是西元年，因为此长度加回去後会超过送出限制，回传结果自行解码後加回去
		String orderId10 = new SimpleDateFormat("yMMddhhmmss").format(new Date());
		String orderIdKey = orderId10.substring(0, 4) + merIdKey + orderId10.substring(4);
		if (orderIdKey.length() > 16) {
			orderIdKey = orderIdKey.substring(0, 16);
		}

		// String transAmt = "000000000001";
		String transAmt = StringUtils.leftPad(
				order.getJoinMustPay().multiply(new BigDecimal("100")).setScale(0).toString(), 12, "0");
		String curyId = "156";// 人民币
		String transDate = new java.text.SimpleDateFormat("yyyyMMdd").format(new java.util.Date());
		String transType = "0001";
		// 产生检查码
		String chkValue = t.signOrder(chinapayId, orderIdKey, transAmt, curyId, transDate, transType);

		Map<String, String> params = new LinkedHashMap<String, String>();// 按照key写入的顺序产生检查码
		params.put("MerId", chinapayId);// 商户号
		params.put("OrdId", orderIdKey);// 订单号，最多16位
		params.put("TransAmt", transAmt);// 交易金额，长度为12个字节的数字串，例如：数字串"000000001234",表示12.34元
		params.put("CuryId", curyId);// 货币代码，目前只支持人民币， 取值为"156" ，
		params.put("TransDate", transDate);// 交易日期
		params.put("TransType", transType);// 交易类型，"0001"表示消费交易，"0002"表示退货交易，
		params.put("Version", "20040916");
		params.put("BgRetUrl", ServerValue.getFrontHostname() + ServerValue.getFrontContextPath()
				+ "/payment/chinapayNotify.do");
		params.put("PageRetUrl", ServerValue.getFrontHostname() + ServerValue.getFrontContextPath()
				+ "/payment/chinapayReturn.do");
		// params.put("GateId", "");
		params.put("Priv1", orderId);
		params.put("ChkValue", chkValue);
		// *********************************************************

		saveSendLog(orderId, order.getJoinMustPay(), "chinaPay", "01", "");
		return params;

	}

	@Override
	public boolean chinapayNotify(Map<String, String> params) {
		String tid = null;// 第三方付款商订单编号
		String orderId = null;// yaodian100订单编号
		BigDecimal amount = null;// 付款数
		boolean isSuccess = false;

		if (chinapayVerify(params)) {

			if (params.containsKey("status")) {
				String status = params.get("status");
				if ("1001".equals(status)) {
					if (params.containsKey("orderno") && params.containsKey("amount")) {
						// tid = params.get("orderno");
						//
						// String thisYear = new SimpleDateFormat("yy").format(new Date());
						// orderId = thisYear + tid.substring(0, 4) + tid.substring(9);
						orderId = params.get("Priv1");
						tid = params.get("orderno");
						// 银联回传金额以分为单位
						amount = new BigDecimal(params.get("amount")).setScale(2).divide(new BigDecimal("100"));
						isSuccess = processThirdparty(orderId, amount, tid, "01", "", params);
					} else {
						insertFailTransfer(orderId, amount, tid, "01", "缺少参数", "", params);
					}
				} else {
					// 交易失败则不再notify
					insertFailTwice("交易失败:" + status, params, "01");
				}
			}
		} else {
			// insertFailTransfer(orderId, amount, tid, "01", "签名验证错误", "", params);
			insertFailTwice("签名验证错误", params, "01");
		}

		return isSuccess;
	}

	@Override
	public boolean chinapayReturn(Map<String, String> params) {
		String tid = null;// 第三方付款商订单编号
		String orderId = null;// yaodian100订单编号
		BigDecimal amount = null;// 付款数
		boolean isSuccess = false;

		if (chinapayVerify(params)) {
			if (params.containsKey("status")) {
				String status = params.get("status");
				if ("1001".equals(status)) {
					if (params.containsKey("orderno") && params.containsKey("amount")) {
						// tid = params.get("orderno");
						//
						// String thisYear = new SimpleDateFormat("yy").format(new Date());
						// orderId = thisYear + tid.substring(0, 4) + tid.substring(9);
						orderId = params.get("Priv1");
						tid = params.get("orderno");
						// 银联回传金额以分为单位
						amount = new BigDecimal(params.get("amount")).setScale(2).divide(new BigDecimal("100"));
						isSuccess = processThirdparty(orderId, amount, tid, "01", "", params);
					} else {
						insertFailTransfer(orderId, amount, tid, "01", "缺少参数", "", params);
					}
				} else {
					// 交易失败则不再notify
					insertFailTwice("交易失败:" + status, params, "01");
				}
			}

		} else {
			// insertFailTransfer(orderId, amount, tid, "01", "签名验证错误", "", params);
			insertFailTwice("签名验证错误", params, "01");
		}

		return isSuccess;

	}

	private boolean chinapayVerify(Map<String, String> params) {
		boolean isValid = false;
		chinapay.PrivateKey key = new chinapay.PrivateKey();
		chinapay.SecureLink t;
		boolean flag = false;

		flag = key.buildKey("999999999999999", 0, keyPath + "/chinapay/PgPubk.key");
		t = new chinapay.SecureLink(key);

		try {
			isValid = t.verifyTransResponse(params.get("merid"), params.get("orderno"), params.get("amount"), params
					.get("currencycode"), params.get("transdate"), params.get("transtype"), params.get("status"), params
					.get("checkvalue")); // ChkValue为ChinaPay应答传回的域段
		} catch (Exception e) {
			e.printStackTrace();
			isValid = false;
		}

		return isValid;
	}

	@Override
	public Map<String, String> quickmoneySend(String orderId, String bankCode) {
		Orders order = orderService.get(orderId);
		String merchantAcctId = quickmoneyId;
		String key = quickmoneyKey;

		// *******************************************
		Map<String, String> signParams = new LinkedHashMap<String, String>();// 按照key写入的顺序产生检查码

		signParams.put("inputCharset", "1");// 1 代表 UTF-8; 2 代表 GBK; 3 代表 GB2312
		signParams.put("pageUrl", ServerValue.getFrontHostname() + ServerValue.getFrontContextPath()
				+ "/payment/quickmoneyReturn.do");
		signParams.put("bgUrl", ServerValue.getFrontHostname() + ServerValue.getFrontContextPath()
				+ "/payment/quickmoneyNotify.do");
		signParams.put("version", "v2.0");
		signParams.put("language", "1");
		signParams.put("signType", "1");
		signParams.put("merchantAcctId", merchantAcctId);// 快錢帳號
		signParams.put("payerName", order.getLoginId());// 用戶名稱
		signParams.put("orderId", orderId);
		// 以分为单位。比方10 元，提交时金额应为 1000
		signParams.put("orderAmount", order.getJoinMustPay().multiply(new BigDecimal("100")).setScale(0).toString());
		signParams.put("orderTime", new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date()));
		signParams.put("productName", "耀点100商品");// 固定商品名稱
		signParams.put("productNum", String.valueOf(order.getOrderProduct().size()));// 商品數量

		if (!StringUtils.isBlank(bankCode)) {
			signParams.put("payType", "10");
			signParams.put("bankId", bankCode);

		} else {
			signParams.put("payType", "12");
		}
		// *************************************************

		Map<String, String> sendParams = new LinkedHashMap<String, String>(signParams);
		sendParams.put("signMsg", DigestUtils.md5Hex(getContent(signParams, "&key=" + key)).toUpperCase());
		// 风险控制字串
		sendParams.put("referDataType", "003_001");
		sendParams.put("referData", StringEscapeUtils.escapeHtml(createJSONForQucikmoney(order)));

		saveSendLog(orderId, order.getJoinMustPay(), "quickmoney", "03", bankCode);

		return sendParams;
	}

	/*
	 * (non-Javadoc) 快錢分期
	 * 
	 * @see com.yaodian100.ec.payment.service.ThirdpartyPaymentService#quickmoneyInstallmentSend(java.lang.String,
	 * java.lang.String)
	 */
	@Override
	public Map<String, String> quickmoneyCreditCardSend(String orderId, String period, String bankCode) {
		Orders order = orderService.get(orderId);
		String merchantAcctId = quickmoneyId;
		String key = quickmoneyInstallmentKey;
		if ("1".equals(period)) {// 單期使用第三方的key
			key = quickmoneyKey;
		}

		// *******************************************
		Map<String, String> signParams = new LinkedHashMap<String, String>();// 按照key写入的顺序产生检查码

		signParams.put("inputCharset", "1");// 1 代表 UTF-8; 2 代表 GBK; 3 代表 GB2312
		signParams.put("pageUrl", ServerValue.getFrontHostname() + ServerValue.getFrontContextPath()
				+ "/payment/quickmoneyReturn.do");
		signParams.put("bgUrl", ServerValue.getFrontHostname() + ServerValue.getFrontContextPath()
				+ "/payment/quickmoneyNotify.do");
		if ("1".equals(period)) {
			signParams.put("version", "v2.0");
		} else {
			signParams.put("version", "200110");
		}
		signParams.put("language", "1");
		signParams.put("signType", "1");
		signParams.put("merchantAcctId", merchantAcctId);// 快錢帳號
		signParams.put("payerName", order.getLoginId());// 用戶名稱
		signParams.put("orderId", orderId);
		// 以分为单位。比方10 元，提交时金额应为 1000
		signParams.put("orderAmount", order.getMustPay().multiply(new BigDecimal("100")).setScale(0).toString());
		signParams.put("orderTime", new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date()));
		signParams.put("productName", "耀点100商品");// 固定商品名稱
		signParams.put("productNum", String.valueOf(order.getOrderProduct().size()));// 商品數量
		if ("1".equals(period)) {
			// signParams.put("pkgCode", "40");//
			signParams.put("payType", "15");// 15 代表信用卡支付
			if (StringUtils.isNotBlank(bankCode)) {
				signParams.put("bankId", bankCode);
			}
			// signParams.put("period", period);
		} else {
			signParams.put("pkgCode", "40");// 40 表示分期付款
			signParams.put("payType", "15");// 15 代表信用卡支付
			signParams.put("period", period);
		}

		// *************************************************

		Map<String, String> sendParams = new LinkedHashMap<String, String>(signParams);
		sendParams.put("signMsg", DigestUtils.md5Hex(getContent(signParams, "&key=" + key)).toUpperCase());
		// 风险控制字串
		sendParams.put("referDataType", "003_001");
		sendParams.put("referData", StringEscapeUtils.escapeHtml(createJSONForQucikmoney(order)));

		saveSendLog(orderId, order.getMustPay(), "quickmoneyCC", "06", period);

		return sendParams;
	}

	/**
	 * @param order
	 */
	private String createJSONForQucikmoney(Orders order) {
		Map<String, Object> riskControlMap = new LinkedHashMap<String, Object>();

		riskControlMap.put("C_NAME", order.getReceiverName());
		riskControlMap.put("C_PHONE", order.getReceiverMobile());
		riskControlMap.put("C_COUNTRY", "CHN");
		riskControlMap.put("C_STATE", order.getReceiverProvince());
		riskControlMap.put("C_CITY", order.getReceiverCity());
		riskControlMap.put("C_ADDRESS", order.getReceiverArea() + order.getReceiverAddr());
		riskControlMap.put("C_ZIPCODE", order.getReceiverZip());

		JSON riskControlJSON = JSONSerializer.toJSON(riskControlMap);
		return riskControlJSON.toString();

	}

	@Override
	public boolean quickmoneyNotify(Map<String, String> params) {
		return quickmoneyNotify(params, "03");

	}

	@Override
	public boolean quickmoneyCreditCardNotify(Map<String, String> params) {
		return quickmoneyNotify(params, "06");

	}

	private boolean quickmoneyNotify(Map<String, String> params, String paymentSrc) {
		String tid = null;// 第三方付款商订单编号
		String orderId = null;// yaodian100订单编号
		BigDecimal amount = null;// 付款数
		String bankCode = params.containsKey("bankId") ? params.get("bankId") : "";
		String installmentPreiod = params.containsKey("period") ? params.get("period") : "";
		boolean isSuccess = false;

		if (quickmoneyVerify(params)) {
			if (params.containsKey("payResult")) {
				String payResult = params.get("payResult");
				if ("10".equals(payResult) || "00".equals(payResult)) {// 快錢有兩種狀態都是成功。00：订单申请成功+10：支付成功
					if (params.containsKey("dealId") && params.containsKey("orderAmount") && params.containsKey("orderId")
							&& params.containsKey("version") && params.containsKey("payType")) {
						// 判斷信用卡（單期，分期）或第三方
						if ("15".equals(params.get("payType"))) {// 信用卡（單期，分期）
							// 分期才會有period這個參數，沒有period代表是單期
							installmentPreiod = params.containsKey("period") ? params.get("period") : "1";
						}

						tid = params.get("dealId");
						// 快钱回传金额以分为单位
						amount = new BigDecimal(params.get("orderAmount")).setScale(2).divide(new BigDecimal("100"));
						orderId = params.get("orderId");
						isSuccess = processThirdparty(orderId, amount, tid, paymentSrc, bankCode, installmentPreiod, params);
					} else {
						insertFailTransfer(orderId, amount, tid, paymentSrc, "缺少参数", bankCode, installmentPreiod, params);
					}
				} else {
					String errCode = params.containsKey("errCode") ? params.get("errCode") : "";
					insertFailTwice("交易失败:" + payResult + "," + errCode, params, paymentSrc);
				}
			}

		} else {
			// insertFailTransfer(orderId, amount, tid, "03", "签名验证错误", bankCode, params);
			insertFailTwice("签名验证错误", params, paymentSrc);
		}

		return isSuccess;

	}

	@Override
	public boolean quickmoneyReturn(Map<String, String> params) {
		return quickmoneyReturn(params, "03");

	}

	@Override
	public boolean quickmoneyCreditCardReturn(Map<String, String> params) {
		return quickmoneyReturn(params, "06");

	}

	private boolean quickmoneyReturn(Map<String, String> params, String paymentSrc) {
		String tid = null;// 第三方付款商订单编号
		String orderId = null;// yaodian100订单编号
		BigDecimal amount = null;// 付款数
		String bankCode = params.containsKey("bankId") ? params.get("bankId") : "";
		String installmentPreiod = "";
		String src = "";

		boolean isSuccess = false;
		if (quickmoneyVerify(params)) {

			if (params.containsKey("payResult")) {
				String payResult = params.get("payResult");
				if ("10".equals(payResult) || "00".equals(payResult)) {

					if (params.containsKey("dealId") && params.containsKey("orderAmount") && params.containsKey("orderId")
							&& params.containsKey("version") && params.containsKey("payType")) {
						// 判斷信用卡（單期，分期）或第三方
						// 判斷信用卡（單期，分期）或第三方
						if ("15".equals(params.get("payType"))) {// 信用卡（單期，分期）
							// 分期才會有period這個參數，沒有period代表是單期
							installmentPreiod = params.containsKey("period") ? params.get("period") : "1";
						}

						tid = params.get("dealId");
						// 快钱回传金额以分为单位
						amount = new BigDecimal(params.get("orderAmount")).setScale(2).divide(new BigDecimal("100"));
						orderId = params.get("orderId");
						isSuccess = processThirdparty(orderId, amount, tid, paymentSrc, bankCode, installmentPreiod, params);
					} else {
						insertFailTransfer(orderId, amount, tid, paymentSrc, "缺少参数", bankCode, installmentPreiod, params);
					}
				} else {
					String errCode = params.containsKey("errCode") ? params.get("errCode") : "";
					insertFailTwice("交易失败:" + payResult + "," + errCode, params, paymentSrc);
				}
			}
		} else {
			// insertFailTransfer(orderId, amount, tid, "03", "签名验证错误", bankCode, params);
			insertFailTwice("签名验证错误", params, paymentSrc);
		}

		return isSuccess;

	}

	private boolean quickmoneyVerify(Map<String, String> params) {
		boolean isValid = false;
		Map<String, String> checkParams = new LinkedHashMap<String, String>();
		String verifyKey = quickmoneyKey;
		try {
			if (StringUtils.isNotBlank(params.get("merchantAcctId"))) {
				checkParams.put("merchantAcctId", params.get("merchantAcctId"));
			}
			if (StringUtils.isNotBlank(params.get("version"))) {
				checkParams.put("version", params.get("version"));
			}
			if (StringUtils.isNotBlank(params.get("language"))) {
				checkParams.put("language", params.get("language"));
			}
			if (StringUtils.isNotBlank(params.get("signType"))) {
				checkParams.put("signType", params.get("signType"));
			}
			if (params.containsKey("pkgCode")) {
				if (StringUtils.isNotBlank(params.get("pkgCode"))) {// 分期才會有的欄位
					checkParams.put("pkgCode", params.get("pkgCode"));
					verifyKey = quickmoneyInstallmentKey;
				}
			}
			if (StringUtils.isNotBlank(params.get("payType"))) {
				// 快錢返回信用卡分期時，有時候沒有，信用卡單期不需要
				if ("15".equals(params.get("payType")) && !checkParams.containsKey("pkgCode") && params.containsKey("period")) {
					checkParams.put("pkgCode", "40");
				}
				checkParams.put("payType", params.get("payType"));

			}
			if (StringUtils.isNotBlank(params.get("bankId"))) {
				checkParams.put("bankId", params.get("bankId"));
			}
			if (StringUtils.isNotBlank(params.get("orderId"))) {
				checkParams.put("orderId", params.get("orderId"));
			}
			if (StringUtils.isNotBlank(params.get("orderTime"))) {
				checkParams.put("orderTime", params.get("orderTime"));
			}
			if (StringUtils.isNotBlank(params.get("orderAmount"))) {
				checkParams.put("orderAmount", params.get("orderAmount"));
			}
			if (StringUtils.isNotBlank(params.get("dealId"))) {
				checkParams.put("dealId", params.get("dealId"));
			}
			if (StringUtils.isNotBlank(params.get("bankDealId"))) {
				checkParams.put("bankDealId", params.get("bankDealId"));
			}
			if (StringUtils.isNotBlank(params.get("dealTime"))) {
				checkParams.put("dealTime", params.get("dealTime"));
			}
			if (StringUtils.isNotBlank(params.get("payAmount"))) {
				checkParams.put("payAmount", params.get("payAmount"));
			}
			if (StringUtils.isNotBlank(params.get("fee"))) {
				checkParams.put("fee", params.get("fee"));
			}
			if (StringUtils.isNotBlank(params.get("ext1"))) {
				checkParams.put("ext1", params.get("ext1"));
			}
			if (StringUtils.isNotBlank(params.get("ext2"))) {
				checkParams.put("ext2", params.get("ext2"));
			}
			if (params.containsKey("period")) {
				if (StringUtils.isNotBlank(params.get("period"))) {// 分期才會有的欄位
					checkParams.put("period", params.get("period"));
					verifyKey = quickmoneyInstallmentKey;
				}
			}
			if (StringUtils.isNotBlank(params.get("payResult"))) {
				checkParams.put("payResult", params.get("payResult"));
			}
			if (StringUtils.isNotBlank(params.get("errCode"))) {
				checkParams.put("errCode", params.get("errCode"));
			}
			// if (!StringUtils.isBlank(params.get("key")))
			checkParams.put("key", verifyKey);

			String checkSign = DigestUtils.md5Hex(getContent(checkParams, "")).toUpperCase();

			String sign = params.get("signMsg");

			if (checkSign.equals(sign)) {
				isValid = true;
			}

		} catch (Exception e) {
			e.printStackTrace();
			isValid = false;
		}

		return isValid;
	}

	@Override
	public Map<String, String> tenpaySend(String orderId, String userIP) {
		Orders order = orderService.get(orderId);

		String bargainorId = tenpayId;
		String key = tenpayKey;

		String today = new java.text.SimpleDateFormat("yyyyMMdd").format(new java.util.Date());
		// String orderId10 = orderId.substring(3);// 前10位为商户网站编号(SPID)+8位为订单产生的日期+10位當天日期
		String orderId10 = new java.text.SimpleDateFormat("MMddHHmmss").format(new java.util.Date());
		String orderIdKey = bargainorId + today + orderId10;
		if (orderIdKey.length() > 28) {
			orderIdKey = orderIdKey.substring(0, 28);
		}

		// *******************************************
		Map<String, String> signParams = new LinkedHashMap<String, String>();

		signParams.put("cmdno", "1");// 业务代码, 财付通支付支付接口填 1
		signParams.put("date", today);// 商户日期：如20051212
		signParams.put("bargainor_id", bargainorId);// 商家的商户号
		signParams.put("transaction_id", orderIdKey);// 交易号(订单号)中前10位为商户网站编号(SPID)+8位为订单产生的日期+10位當天日期
		signParams.put("sp_billno", orderId);// 商户系统内部的定单号
		signParams.put("total_fee", order.getJoinMustPay().multiply(new BigDecimal("100")).setScale(0).toString());// 总金额，以分为单位
		signParams.put("fee_type", "1");// 现金支付币种，1 – RMB 人民币
		signParams.put("return_url", ServerValue.getFrontHostname() + ServerValue.getFrontContextPath()
				+ "/payment/tenpayNotify.do");// 接收财付通返回结果

		signParams.put("attach", orderId);// 商家数据包，原样返回
		signParams.put("spbill_create_ip", userIP);// 用户IP（非商户服务器IP）

		// *************************************************

		Map<String, String> sendParams = new LinkedHashMap<String, String>(signParams);
		sendParams.put("sign", DigestUtils.md5Hex(getContent(signParams, "&key=" + key)).toLowerCase());
		sendParams.put("bank_type", "0");// 银行类型:财付通支付填0
		sendParams.put("purchaser_id", order.getReceiverEmail());// 用户(买方)的财付通帐户(QQ或EMAIL)

		saveSendLog(orderId, order.getJoinMustPay(), "tenpay", "02", "");

		return sendParams;
	}

	@Override
	public boolean tenpayReturn(Map<String, String> params) {
		String tid = null;
		String orderId = null;
		BigDecimal amount = null;
		boolean isSuccess = false;

		if (tenpayVerify(params)) {
			if (params.containsKey("pay_result")) {
				String payResult = params.get("pay_result");
				if ("0".equals(payResult)) {
					if (params.containsKey("transaction_id") && params.containsKey("total_fee")
							&& params.containsKey("sp_billno")) {
						tid = params.get("transaction_id");
						// 财付通回传金额以分为单位
						amount = new BigDecimal(params.get("total_fee")).setScale(2).divide(new BigDecimal("100"));
						orderId = params.get("sp_billno");
						isSuccess = processThirdparty(orderId, amount, tid, "02", "", params);
					} else {
						insertFailTransfer(orderId, amount, tid, "02", "缺少参数", "", params);

					}
				} else {
					insertFailTwice("交易失败:" + payResult, params, "02");
				}
			}

		} else {
			// insertFailTransfer(orderId, amount, tid, "02", "签名验证错误", "", params);
			insertFailTwice("签名验证错误", params, "02");
		}
		return isSuccess;
	}

	private boolean tenpayVerify(Map<String, String> params) {
		boolean isValid = false;
		Map<String, String> checkParams = new LinkedHashMap<String, String>();

		try {
			if (!StringUtils.isBlank(params.get("cmdno"))) {
				checkParams.put("cmdno", params.get("cmdno"));
			}
			if (!StringUtils.isBlank(params.get("pay_result"))) {
				checkParams.put("pay_result", params.get("pay_result"));
			}
			if (!StringUtils.isBlank(params.get("date"))) {
				checkParams.put("date", params.get("date"));
			}
			if (!StringUtils.isBlank(params.get("transaction_id"))) {
				checkParams.put("transaction_id", params.get("transaction_id"));
			}
			if (!StringUtils.isBlank(params.get("sp_billno"))) {
				checkParams.put("sp_billno", params.get("sp_billno"));
			}
			if (!StringUtils.isBlank(params.get("total_fee"))) {
				checkParams.put("total_fee", params.get("total_fee"));
			}
			if (!StringUtils.isBlank(params.get("fee_type"))) {
				checkParams.put("fee_type", params.get("fee_type"));
			}
			if (!StringUtils.isBlank(params.get("attach"))) {
				checkParams.put("attach", params.get("attach"));
			}
			// if (!StringUtils.isBlank(params.get("key")))
			checkParams.put("key", tenpayKey);

			String checkSign = DigestUtils.md5Hex(getContent(checkParams, "")).toUpperCase();

			String sign = params.get("sign");

			if (checkSign.equals(sign)) {
				isValid = true;
			}

		} catch (Exception e) {
			e.printStackTrace();
			isValid = false;
		}

		return isValid;
	}

	private static String getContent(Map<String, String> params, String privateKey) {
		List<String> keys = new ArrayList<String>(params.keySet());
		// Collections.sort(keys);

		String prestr = "";

		boolean first = true;
		for (int i = 0; i < keys.size(); i++) {
			String key = keys.get(i);
			String value = params.get(key);
			if (value == null || value.trim().length() == 0) {
				continue;
			}
			if (first) {
				prestr = prestr + key + "=" + value;
				first = false;
			} else {
				prestr = prestr + "&" + key + "=" + value;
			}
		}
		logger.info("getContent:{}", prestr + privateKey);
		return prestr + privateKey;
	}

	private void saveSendLog(String orderId, BigDecimal amount, String tid, String src, String bankCode) {

		ThirdPartyTransferLog transferlog = new ThirdPartyTransferLog();
		transferlog.setOrderId(orderId);
		transferlog.setAmount(amount);
		transferlog.setTid(tid);
		transferlog.setSendDt(new Date());
		transferlog.setSrc(src);
		transferlog.setBankCode(bankCode);

		thirdpartyTransferLogService.save(transferlog);

	}

	/**
	 * @param orderId 訂單編號
	 * @param amount 第三方回傳的付款數字
	 * @param tid 弟三方付款商的訂單編號
	 * @param src 第三方付款商類別
	 * @return
	 */
	private boolean processThirdparty(String orderId, BigDecimal amount, String tid, String src, String bankCode,
			Map<String, String> params) {
		return processThirdparty(orderId, amount, tid, src, bankCode, "", params);
	}

	/**
	 * @param orderId 訂單編號
	 * @param amount 第三方回傳的付款數字
	 * @param tid 弟三方付款商的訂單編號
	 * @param src 第三方付款商類別
	 * @param period 第三方付款分期期數
	 * @return
	 */
	@Transactional(readOnly = false)
	private boolean processThirdparty(String orderId, BigDecimal amount, String tid, String src, String bankCode,
			String period, Map<String, String> params) {
		boolean isSuccess = false;
		Orders order = orderService.get(orderId);
		ThirdPartyTransfer thirdpartyTransfer = new ThirdPartyTransfer();
		amount.setScale(2);

		try {
			// 檢查訂單編號是否存在和付款金額是否相符，以及訂單付款方法為第三方支付
			if (null != order
					&& (order.getJoinMustPay().compareTo(amount) == 0)
					&& "10".equals(order.getOrderSt())
					&& ("50".equals(order.getPaymentTp()) || "70".equals(order.getPaymentTp()) || "80".equals(order
							.getPaymentTp()))) {
				thirdpartyTransfer.setOrderId(orderId);
				thirdpartyTransfer.setResult("0000");// 交易成功与否
				thirdpartyTransfer.setSrc(src);
				thirdpartyTransfer.setStatus("10");// 交易状态
				thirdpartyTransfer.setTid(tid);
				thirdpartyTransfer.setTradeEndDt(new Date());
				thirdpartyTransfer.setTradeStartDt(new Date());
				thirdpartyTransfer.setAmount(amount);
				thirdpartyTransfer.setBankCode(bankCode);
				thirdpartyTransfer.setUserPost(period);// 分期付款期數
				thirdpartyTransfer = transferService.save(thirdpartyTransfer);

				// 第三方成功付款紀錄寫入和訂單是否寫入成功
				if (orderService.charge(orderId, thirdpartyTransfer.getId(), amount, src)
						&& !(StringUtils.isBlank(thirdpartyTransfer.getId()))) {
					// orderService.sendApplyClaimMail("order.gotMoney", order);// 發信
					batchJobService.save("EC-ThirdpartyTransferJob", toXML(thirdpartyTransfer), null, order.getOrderId());
					isSuccess = true;
				} else {
					isSuccess = insertFailTransfer(orderId, amount, tid, src, "更新订单失败：" + orderId, bankCode, period, params);
				}
			} else {
				isSuccess = insertFailTransfer(orderId, amount, tid, src, "订单不存在或付款金额不符或订单状态非(10 訂單成立)：" + orderId + ","
						+ amount, bankCode, period, params);
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
			if (null != transferService.get(orderId)) {
				isSuccess = insertFailTransfer(orderId, amount, tid, src, " 非重复order_id写入的例外產生：" + e, bankCode, params);
			} else {
				isSuccess = insertFailTransfer(orderId, amount, tid, src,
						"EC_THIRD_PARTY_TRANSFER已經存在此筆order_id資料，可能用户使用第二种线上付款方式：" + orderId + "," + e, bankCode, params);
			}

		}

		return isSuccess;
	}

	private boolean insertFailTransfer(String orderId, BigDecimal amount, String tid, String src, String note,
			String bankCode, Map<String, String> params) {
		return insertFailTransfer(orderId, amount, tid, src, note, bankCode, "", params);
	}

	@Transactional(readOnly = false)
	private boolean insertFailTransfer(String orderId, BigDecimal amount, String tid, String src, String note,
			String bankCode, String period, Map<String, String> params) {

		boolean asSuccess = false;// 是否作為成功處理

		// 由於notify和return是不同時機點，所以先檢查是否已有相同ORDER_ID+TID+SRC的資料在EC_THIRD_PARTY_TRANSFER中，
		// 才寫入EC_THIRD_PARTY_TRANSFER，避免造成退款作業的重複
		CommonCriteria cc = new CommonCriteria();
		cc.addEq("orderId", orderId);
		cc.addEq("tid", tid);
		cc.addEq("src", src);

		Number thirdpartyTransferSize = transferService.getListSize(cc);
		ThirdPartyTransferFail thirdpartyTransferFail = new ThirdPartyTransferFail();
		if (thirdpartyTransferSize.intValue() <= 0) {
			try {
				thirdpartyTransferFail.setOrderId(orderId);
				thirdpartyTransferFail.setResult("0000");// 交易成功与否
				thirdpartyTransferFail.setSrc(src);
				thirdpartyTransferFail.setStatus("10");// 交易状态
				thirdpartyTransferFail.setTid(tid);
				thirdpartyTransferFail.setTradeEndDt(new Date());
				thirdpartyTransferFail.setTradeStartDt(new Date());
				thirdpartyTransferFail.setAmount(amount);
				thirdpartyTransferFail.setUserNote(StringUtils.abbreviate(note, 340));// 防止錯誤原因過長。
				thirdpartyTransferFail.setBankCode(bankCode);
				thirdpartyTransferFail.setUserPost(period);// 分期付款期數
				thirdpartyTransferFail = thirdpartyTransferFailService.save(thirdpartyTransferFail);
				batchJobService.save("EC-ThirdpartyTransferFailJob", toXML(thirdpartyTransferFail), null, orderId);
				asSuccess = true;
			} catch (ConstraintViolationException e) {
				asSuccess = true;
			} catch (Exception e) {
				e.printStackTrace();
				insertFailTwice(note + "," + e.getMessage(), params, src);

			}
		} else {
			StringBuffer sb = new StringBuffer(note).append(",EC_THIRD_PARTY_TRANSFER已經存在此筆order_id+src+tid的資料：");
			sb.append(orderId).append(",");
			sb.append(src).append(",").append(tid);
			// /insertFailTwice(sb.toString(), params, src);20101103，此種紀錄不再發信通知
			params.put("errors", sb.toString());
			logService.save("ThirdpartyPaymentServiceImpl", "ThirdpartyPaymentDuplicate", params, src);
			// 當成功的原因是EC_THIRD_PARTY_TRANSFER已經存在此筆order_id資料，可能在return時就已成功寫入，
			// 但第三方廠商在背景仍會已notify通知，以此告知第三方廠商不須再繼續notify
			asSuccess = true;
		}

		return asSuccess;
	}

	@Transactional(readOnly = false)
	private void insertFailTwice(String errMsg, Map<String, String> params, String src) {
		// JSON json = JSONSerializer.toJSON(params);
		StringBuffer sb = new StringBuffer(errMsg);
		sb.append(", params=").append(params);
		sb.append(", src=").append(src);

		Mail mail = new Mail("thirdparty Error", sb.toString(), "afra.chou@yaodian100.com", "");
		mailService.save(mail);

		params.put("errors", errMsg);
		logService.save("ThirdpartyPaymentServiceImpl", "ThirdpartyPaymentFail", params, src);
	}

	private String toXML(Object entity) {
		String xml = null;
		try {

			StringWriter sw = new StringWriter();
			BeanWriter beanWriter = new BeanWriter(sw);
			beanWriter.enablePrettyPrint();
			beanWriter.getBindingConfiguration().setMapIDs(false);
			beanWriter.write(entity);
			xml = sw.toString();
			beanWriter.flush();
			beanWriter.close();
		} catch (Exception e) {
			logger.info("to XML Exception:{}", e);

		}
		return xml;

	}

	@Transactional(readOnly = false)
	public void retry3rdPartyFail() {
		String sql = "select id from ec_third_party_transfer where order_id not in (select order_id from ec_order_main where payment_st = '10' and payment_tp in ('50','70','80'))";
		List<Map<String, Object>> tpt = jdbcTemplate.queryForList(sql.toString());
		ArrayList<String> all = new ArrayList<String>();
		ArrayList<String> sucess = new ArrayList<String>();
		ArrayList<String> over = new ArrayList<String>();
		ArrayList<String> fail = new ArrayList<String>();

		for (Map<String, Object> obj : tpt) {
			ThirdPartyTransfer thirdpartyTransfer = transferService.get((String) obj.get("id"));
			all.add(thirdpartyTransfer.getOrderId());
			if (null != thirdpartyTransfer
					&& "10".equals(orderService.get(thirdpartyTransfer.getOrderId()).getOrderSt())
					&& orderService.charge(thirdpartyTransfer.getOrderId(), thirdpartyTransfer.getId(), thirdpartyTransfer
							.getAmount(), thirdpartyTransfer.getSrc())) {

				batchJobService.save("EC-ThirdpartyTransferJob", toXML(thirdpartyTransfer), null, thirdpartyTransfer
						.getOrderId());
				sucess.add(thirdpartyTransfer.getOrderId());

			} else {
				// 訂單已被取消才轉溢收
				if ("80".equals(orderService.get(thirdpartyTransfer.getOrderId()).getOrderSt())
						|| "81".equals(orderService.get(thirdpartyTransfer.getOrderId()).getOrderSt())
						|| "82".equals(orderService.get(thirdpartyTransfer.getOrderId()).getOrderSt())) {
					ThirdPartyTransferFail thirdpartyTransferFail = new ThirdPartyTransferFail();
					try {

						thirdpartyTransferFail.setOrderId(thirdpartyTransfer.getOrderId());
						thirdpartyTransferFail.setResult(thirdpartyTransfer.getResult());// 交易成功与否
						thirdpartyTransferFail.setSrc(thirdpartyTransfer.getSrc());
						thirdpartyTransferFail.setStatus(thirdpartyTransfer.getStatus());// 交易状态
						thirdpartyTransferFail.setTid(thirdpartyTransfer.getTid());
						thirdpartyTransferFail.setTradeEndDt(thirdpartyTransfer.getTradeEndDt());
						thirdpartyTransferFail.setTradeStartDt(thirdpartyTransfer.getTradeStartDt());
						thirdpartyTransferFail.setAmount(thirdpartyTransfer.getAmount());
						thirdpartyTransferFail.setUserNote("订单" + thirdpartyTransfer.getOrderId() + "收款错误由成功记录"
								+ thirdpartyTransfer.getId() + "转入");
						thirdpartyTransferFail.setBankCode(thirdpartyTransfer.getBankCode());
						thirdpartyTransferFail = thirdpartyTransferFailService.save(thirdpartyTransferFail);
						batchJobService.save("EC-ThirdpartyTransferFailJob", toXML(thirdpartyTransferFail), null,
								thirdpartyTransfer.getOrderId());

						transferService.delete(thirdpartyTransfer);// 做完之後把成功的刪掉
						over.add(thirdpartyTransfer.getOrderId());
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						fail.add(thirdpartyTransfer.getOrderId());

					}
				}
			}

		}
		if (!tpt.isEmpty()) {
			StringBuffer sb = new StringBuffer().append(tpt);
			sb.append("<br>补收款成功=>").append(sucess);
			sb.append("<br>收款转溢收=>").append(over);
			sb.append("<br>异常=>").append(fail);

			Mail mail = new Mail("补收款批次作业", sb.toString(), "afra.chou@yaodian100.com", null);
			mail.setFrom("system@yaodian100.com");
			mailService.save(mail);
		}

	}

	public boolean isVaildCreditCardSendInfo(String orderId, String period, String bankCode) {
		boolean result = false;
		Orders order = orderService.get(orderId);
		if (null != order) {
			if (null != order.getOrderCreditCardCampaign()) {
				// String productId, String bankId, String period, String cookie, String domain
				String productId = order.getOrderProduct().get(0).getProdId();
				String creditcardDetailId = Long.toString(order.getOrderCreditCardCampaign().getCreditcardDetailId());
				String periodInOrder = order.getOrderCreditCardCampaign().getCreditcartPeriod();
				String cookie = order.getChannel();
				String domain = order.getDomainSrc();
				CreditcardDetail ccd = creditcardService.getValidCreditcard(productId, creditcardDetailId, period, cookie,
						domain);
				if (null != ccd && period.equals(periodInOrder) && ccd.getPeriodMap().containsKey(period)) {
					result = true;
				}
			}

		}

		return result;
	}

	public String invaildCreditCardNotify(String orderId, String tid) {

		CommonCriteria cc = new CommonCriteria();
		cc.addEq("orderId", orderId);
		cc.addEq("tid", tid);

		List<ThirdPartyTransfer> tpts = transferService.getList(0, -1, cc, new String[] { "orderId" });
		if (tpts.size() == 0) {
			return "查無資料：" + orderId + "," + tid;
		}

		for (ThirdPartyTransfer tpt : tpts) {
			Orders order = orderService.get(tpt.getOrderId());
			if (null != order) {
				if (!order.isSync()) {
					try {
						orderService.cancelOrderByCreditCardNotidy(order);
					} catch (CoreException e) {
						e.printStackTrace();
						return e.getMessage();
					}

				} else {
					return "订单已同步至后台";
				}
			} else {
				return "订单不存在";
			}
		}

		return "true";
	}
}
